export class KeyboardInput {
  #wasStarted = false;
  #wasFinished = false;

  #pressedKeys: Record<string, boolean> = {};

  get wasStarted(): boolean {
    return this.#wasStarted;
  }

  get wasFinished(): boolean {
    return this.#wasFinished;
  }

  get state(): Record<string, boolean> {
    return { ...this.#pressedKeys };
  }

  checkIfAnyKeyIsDown(): boolean {
    return Object.values(this.#pressedKeys).some((i) => i);
  }

  checkIfKeyIsDown(key: string): boolean {
    return this.#pressedKeys[key];
  }

  start() {
    if (this.wasStarted) {
      throw new Error('Keyboard input is already started');
    }

    this.addEventListeners();
  }

  finish() {
    if (this.wasFinished) {
      throw new Error('Keyboard input is already finished');
    }

    this.#pressedKeys = {};
    this.removeEventListeners();
  }

  private onKeyDown = (event: KeyboardEvent) => {
    this.#pressedKeys[event.code] = true;
  };

  private onKeyUp = (event: KeyboardEvent) => {
    this.#pressedKeys[event.code] = false;
  };

  private addEventListeners() {
    document.addEventListener('keydown', this.onKeyDown);
    document.addEventListener('keyup', this.onKeyUp);
  }

  private removeEventListeners() {
    document.removeEventListener('keydown', this.onKeyDown);
    document.removeEventListener('keyup', this.onKeyUp);
  }
}
